<?php
defined('BASE_DIR') or die('No direct script access allowed');

/**
 * DolphinGTK - phpGtk framework
 *
 * @package    DolphinGTK
 * @author     Askarov Ruslan
 * @copyright  Askarov Ruslan (c) 2010.
 * @link       http://groups.google.com/group/dolphingtk
 * @license    http://www.opensource.org/licenses/gpl-license.php GPL
 * @version    0.1
 * @since      PHP v.: 5.2.1
 * @subpackage desktop
 * @category   library
 * @filesource
 */

final class Sqlite
{
  # указатель на соединение
  private $conn_id;

  # результат выполнения запроса
  private $result;

  # sql запрос
  public  $my_query;

  private static $dbname;



  /**
   * Функция обработки ошибок
   *
   * если есть какие либо ошибки,
   * то ссылаемся на данный метод
   * а тут просто указываем как отработать
   * ошибки. по умолчанию выводим ошибку
   * и отправляем письмо админстратору
   *
   * @access  public
   * @param  string $error  - ошибка которая возникла
   * @return  void
   */
  protected function display_err( $error )
  {
    # в зависимости от вывода ошибок показываем или пишем в лог ошибку
    print("
    Class Sqlite. Error message:
    $error
    Sql: {$this->my_query}");

    # завершаем работу
    exit;
  }




  /**
   * Метод инициализируемый при первом вызове
   * класса.
   *
   * функция которая подключается к БД и задает кодировку
   * которую использует непосредственно сайт.
   *
   * @access  public
   * @return  void
   */
  public function __construct( $dbname = false )
  {
    self::$dbname = $dbname;
  }




  /**
   * Коннект к БД
   *
   * @access  protected
   * @return  void
   */
  public function connect()
  {
    if( empty(self::$dbname) ) {
      self::display_err('Введите имя БД');
      return false;
    }

    $conn_id = @sqlite_open(self::$dbname, 0666, $error);

    if( !$conn_id ) {
      self::display_err('Соединение с Базами данных отсутствует! ' . $error);
    } else {
      $this->conn_id = $conn_id;
    }
  }




  /**
   * Функия запроса к БД
   *
   * в случае успешного запроса, возвращается
   * булеево значение 'true' или 'false' в
   * случае неудачи
   *
   * @access  public
   * @param  string $query  - sql запрос
   * @return  bool
   */
  public function query( $query )
  {
    # сохраняем запрос
    $this->my_query = $query;

    $this->result = @sqlite_query( $this->conn_id, $query );

    if ( !$this->result )
    {
      $errors = sqlite_error_string(sqlite_last_error($this->conn_id));
      self::display_err( $errors );
    }
    else
    {
      return true;
    }
  }




  /**
   * Получение числа результата
   *
   * @access  public
   * @return  integer
   */
  public function num()
  {
    return @sqlite_num_rows($this->result);
  }




  /**
   * Получение "id" последнего рядя
   *
   * @access  public
   * @return  integer
   */
  public function insert_id()
  {
    return @sqlite_last_insert_rowid($this->conn_id);
  }



  
  public function escape($str)
  {
    if( ini_get('magic_quotes_runtime') == false )
    {
      if(is_array($str))
      {
        foreach($str as $key => $value)
        {
          $key   = sqlite_escape_string($key);
          $value = sqlite_escape_string($value);

          $str[$key] = $value;
        }

        return $str;
      }
      else
      {
        return sqlite_escape_string($str);
      }
    }
    else
    {
      return $str;
    }
  }




  /**
   * Получение результата с одной ячейки
   *
   * @access  public
   * @param   $i - ячейка из ряда
   * @return  string
   */
  public function result( $i = 0 )
  {
    if( $this->result )
    {
      self::query($this->my_query);
      $obj = @sqlite_fetch_object($this->result);
    }
    else
    {
      return false;
    }

    return $obj[$i];
  }




  /**
   * Получение рядов результата выборки
   *
   * @access public
   * @return array
   */
  public function fetch()
  {
    while( $res = @sqlite_fetch_array($this->result) ):
      foreach($res as $key => $value):
      $res[$key] = $value;
      endforeach;
    $result[] = $res;
    endwhile;

    return $result;
  }




  /**
   * Создания дополнительных параметров выборки
   *
   * @access protected
   * @param  $where - массив данных
   * @return string sql
   */
  protected function where( $where = false, $table )
  {
    if( is_array( $where ) )
    {
      $where = self::escape($where);

      foreach($where as $key => $value):
      if(is_numeric($key))
      {
        $key = "id";
        $or ++;
      }
      $end_where[] = " $key = '$value' ";
      endforeach;

      $split = implode( (( $or == count($where) ) ? ' or ' : ' and '), $end_where);
      return  'where ' . $split;
    }

  }




  /**
   * Вставка рядов в таблицу
   *
   * @access  public
   * @param $table     - таблица
   * @param $array     - данные
   * @param $exception - исключения ключей
   * @return void
   */
  public function insert($table, $array = false, $exception = false)
  {
    if( $exception ) {
      foreach($exception as $key):
        unset($array[$key]);
      endforeach;
    }

    $array = self::escape( $array );

    if( count($array) > 0 && !empty($table) ) {

      self::query(
        "INSERT INTO ".$table."
        (".implode(', ', array_keys($array)).") 
          VALUES 
        ('".implode("' , '", array_values($array))."')"
      );
    }
  }




  /**
   * Метод удаления рядов с таблицы
   *
   * @access protected
   * @param  $table - таблица
   * @param  $where - массив данных
   * @return void
   */
  public function delete($table, $where = false)
  {
    self::query( "delete from $table " . self::where( $where, $table ) );
  }




  /**
   * Обновления данных в ряду или таблице
   *
   * @access public
   * @param  $table     - таблица
   * @param  $array     - данные в виде массива
   * @param  $where     - указатель для выборки ряда(ов)
   * @param  $exception - исключение ключей
   * @return void
   */
  public function update($table, $array, $where = false, $exception = false)
  {
    if( $exception ) {
      foreach($exception as $key):
        unset($array[$key]);
      endforeach;
    }

    if(count($array) > 0) {
      $array = self::escape($array);

      foreach($array as $key => $value):
      $data[] = " $key='$value' ";
      endforeach;

      $where = self::where($where, $table);
      self::query( "update $table set " . implode(', ', $data) . $where );
    }
  }




  /**
   * Получаем целостный результат
   *
   * @access public
   * @param  $table - таблица
   * @param  $where - указатель для выборки ряда(ов)
   * @param  $limit - true или false. нужно обязательно указывать
   *                  set_limit()
   * @param  $order - сортировка. если используем set_like и match,
   *                  то сортировка не работает
   * @return array(num & result)
   */
  public function select($table, $where = false, $limit = false, $order = false)
  {
    // если есть лимитинг
    if( $limit ) {
      $limit =  ' limit ' . START_PAGE . ', ' . END_PAGE;
    }

    // коль присутствует сортировка
    if( $order ) {
      $order =  " order by $order";
    }

    // сначала получим запрос где
    $conv_where = self::where($where, $table);

    $add_to_sql = $conv_where . $order . $limit;

    self::query( "select * from $table " . $add_to_sql );
    $result = self::fetch();

    if( $limit )
    {
      self::query( "select count(*) from $table " . $conv_where );

      $obj = @mysqli_fetch_array($this->result);
      $num = $obj[0];
    }
    else
    {
      $num = self::num();
    }

    return array('result' => $result, 'num' => $num);

  }



  /**
   * Разрываем соединение с БД
   *
   * @access public
   * @return void
   */
  public function disconnect()
  {
    @sqlite_close($this->conn_id);
  }

}
?>
